package com.ryan.mms.privilage.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ryan.framework.dto.DtoUtil;
import com.ryan.framework.tag.pagination.Page;
import com.ryan.mms.organization.dto.OrganizationDto;
import com.ryan.mms.organization.model.Organization;
import com.ryan.mms.position.dto.PositionDto;
import com.ryan.mms.position.model.Position;
import com.ryan.mms.privilage.dao.EmployeeDao;
import com.ryan.mms.privilage.dto.EmployeeDto;
import com.ryan.mms.privilage.model.Employee;
import com.ryan.mms.privilage.service.EmployeeService;

@Service
public class EmployeeServiceImpl implements EmployeeService<EmployeeDto,Employee,Long>{
	
	@Autowired
	private EmployeeDao<Employee,Long> employeeDao;


	@SuppressWarnings("unchecked")
	private DtoUtil<EmployeeDto,Employee> employeeDtoUtil = DtoUtil.getInstance(EmployeeDto.class, Employee.class);
	
	@SuppressWarnings("unchecked")
	private DtoUtil<OrganizationDto,Organization> organizationDtoUtil = DtoUtil.getInstance(OrganizationDto.class, Organization.class);

	@SuppressWarnings("unchecked")
	private DtoUtil<PositionDto,Position> positionDtoUtil = DtoUtil.getInstance(PositionDto.class, Position.class);
	
	public EmployeeDto save(final EmployeeDto dto) {
		Employee model = employeeDtoUtil.convertDto2Model(dto);
		model.setOrganization(organizationDtoUtil.convertDto2Model(dto.getOrganizationDto()));
		model.setPositions(positionDtoUtil.convertDtos2Models(dto.getPositionDtos()));
		employeeDao.save(model);
		EmployeeDto result = employeeDtoUtil.convertModel2Dto(model);
		result.setOrganizationDto(organizationDtoUtil.convertModel2Dto(model.getOrganization()));
        return result;
    }
    
    public EmployeeDto update(final EmployeeDto dto) {
        return save(dto);
    }
    
	public void delete(final EmployeeDto dto) {
		Employee model = employeeDtoUtil.convertDto2Model(dto);
        employeeDao.delete(model);
    }

	public void deleteById(Long pk) {
		employeeDao.delete(pk);
    }

	public EmployeeDto findById(Long pk) {
		Employee model = employeeDao.get(pk);
		EmployeeDto employeeDto = employeeDtoUtil.convertModel2Dto(model);
		employeeDto.setOrganizationDto(organizationDtoUtil.convertModel2Dto(model.getOrganization()));
//		employeeDto.setPositionDtos(positionDtoUtil.convertModels2Dtos(model.getPositions()));
        return employeeDto;
    }

	public List<EmployeeDto> getAll() {
        List<Employee> models = employeeDao.getAll();
        List<EmployeeDto> dtos = new ArrayList<EmployeeDto>();
        for(Employee employee:models){
        	EmployeeDto employeeDto = employeeDtoUtil.convertModel2Dto(employee);
        	employeeDto.setOrganizationDto(organizationDtoUtil.convertModel2Dto(employee.getOrganization()));
        	employeeDto.setPositionDtos(positionDtoUtil.convertModels2Dtos(employee.getPositions()));
        	dtos.add(employeeDto);
        }
        return dtos;
    }

	public List<EmployeeDto> getAll(final Page page) {
        List<Employee> models = employeeDao.getAll(page);
        List<EmployeeDto> dtos = new ArrayList<EmployeeDto>();
        for(Employee employee:models){
        	EmployeeDto employeeDto = employeeDtoUtil.convertModel2Dto(employee);
        	employeeDto.setOrganizationDto(organizationDtoUtil.convertModel2Dto(employee.getOrganization()));
        	employeeDto.setPositionDtos(positionDtoUtil.convertModels2Dtos(employee.getPositions()));
        	dtos.add(employeeDto);
        }
        return dtos;
    }

	public EmployeeDto doInIsolatedTx(EmployeeDto dto) {
		Employee model = employeeDtoUtil.convertDto2Model(dto);
		model.setOrganization(organizationDtoUtil.convertDto2Model(dto.getOrganizationDto()));
		Employee savedModel = this.employeeDao.save(model);
		EmployeeDto employeeDto =employeeDtoUtil.convertModel2Dto(savedModel);
    	employeeDto.setOrganizationDto(organizationDtoUtil.convertModel2Dto(savedModel.getOrganization()));
    	employeeDto.setPositionDtos(positionDtoUtil.convertModels2Dtos(savedModel.getPositions()));
		return employeeDto;
	}


	public EmployeeDto findByName(String name) {
		return employeeDtoUtil.convertModel2Dto(employeeDao.findUniqueBy("name", name));
	}


	public void deleteAll(List<Long> pks) {
		employeeDao.deleteByEmployeeIds(pks);
	}


	public void setEmployeeDao(EmployeeDao<Employee, Long> employeeDao) {
		this.employeeDao = employeeDao;
	}

	public List<EmployeeDto> find(Page page, EmployeeDto employeeDto) {
		List<Employee> models = new ArrayList<Employee>();
		if(null!=employeeDto&&null!=page){
			Employee model = employeeDtoUtil.convertDto2Model(employeeDto);
			model.setOrganization(organizationDtoUtil.convertDto2Model(employeeDto.getOrganizationDto()));
			model.setPositions(positionDtoUtil.convertDtos2Models(employeeDto.getPositionDtos()));
			models= employeeDao.findByEmployee(page,model);
		}else if(page==null&&employeeDto==null){
			models=employeeDao.getAll();
		}else if(employeeDto==null&&null!=page){
			models=employeeDao.getAll(page);
		}else{
			Employee model = employeeDtoUtil.convertDto2Model(employeeDto);
			model.setOrganization(organizationDtoUtil.convertDto2Model(employeeDto.getOrganizationDto()));
			model.setPositions(positionDtoUtil.convertDtos2Models(employeeDto.getPositionDtos()));
			models=employeeDao.findByEmployee(model);
		}
        List<EmployeeDto> dtos = new ArrayList<EmployeeDto>();
        for(Employee employee:models){
        	EmployeeDto employeeDtoTemp = employeeDtoUtil.convertModel2Dto(employee);
        	employeeDtoTemp.setOrganizationDto(organizationDtoUtil.convertModel2Dto(employee.getOrganization()));
        	employeeDtoTemp.setPositionDtos(positionDtoUtil.convertModels2Dtos(employee.getPositions()));
        	employeeDtoTemp.setPositionDtos(positionDtoUtil.convertModels2Dtos(employee.getPositions()));
        	dtos.add(employeeDtoTemp);
        }
		return dtos;
	}
}
